using Avalonia.Media.Imaging;
using AzrngTools.Utils;
using AzrngTools.Utils.Events;
using Common.Extension;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Processing;

namespace AzrngTools.ViewModels.Image;

/// <summary>
/// icon转换
/// </summary>
public partial class IcoToConvertPageViewModel : ViewModelBase
{
    private readonly IMessageService _messageService;

    public IcoToConvertPageViewModel(IMessageService messageService)
    {
        _messageService = messageService;
    }

    /// <summary>
    /// 选择的文件路径
    /// </summary>
    [ObservableProperty]
    private string _selectPath;

    /// <summary>
    /// 图片尺寸
    /// </summary>
    [ObservableProperty]
    private int _imageResizerIndex;

    /// <summary>
    /// 选择文件
    /// </summary>
    [RelayCommand]
    private async Task SelectFilesAsync()
    {
        var selectFileList = await DialogHelper.OpenFileDialogAsync(this, "请选择文件", false);
        if (selectFileList is null || !selectFileList.Any())
        {
            _messageService.SendMessage("请选择文件");
            return;
        }

        SelectPath = selectFileList.First();
    }

    /// <summary>
    /// 保存文件
    /// </summary>
    /// <returns></returns>
    [RelayCommand]
    private async Task ConvertSaveFileAsync()
    {
        if (SelectPath.IsNullOrWhiteSpace())
        {
            _messageService.SendMessage("请选择图片");
            return;
        }

        var widthHeight = 32;
        widthHeight = ImageResizerIndex switch
        {
            0 => 16,
            1 => 32,
            2 => 48,
            3 => 64,
            4 => 128,
            _ => widthHeight
        };

        var fs = SelectPath.Split('\\').Last();
        var filePath = SelectPath.Replace(fs, "");
        var fileName = $"favicon_{widthHeight}_{DateTime.Now:HHmmssfff}.ico";

        var isSuccess = await ConvertImageToIconAsync(SelectPath, Path.Combine(filePath, fileName), widthHeight, widthHeight);
        if (!isSuccess)
        {
            _messageService.SendMessage("生成失败");
            return;
        }

        _messageService.SendMessage("生成成功");
    }

    /// <summary>
    /// ICON图标文件头模板
    /// </summary>
    private static readonly byte[] ICON_HEAD_TEMPLATE =
    [
        0x00,
        0x00,
        0x01,
        0x00,
        0x01,
        0x00,
        0x80,
        0x80,
        0x00,
        0x00,
        0x00,
        0x00,
        0x20,
        0x00,
        0xC4,
        0x6E,
        0x00,
        0x00,
        0x16,
        0x00,
        0x00,
        0x00
    ];

    /// <summary>
    /// 图片转换为ico文件
    /// </summary>
    /// <param name="origin">原图片路径</param>
    /// <param name="destination">输出ico文件路径</param>
    /// <param name="width">输出ico图标尺寸，不可大于255x255</param>
    /// <param name="height">输出ico图标尺寸，不可大于255x255</param>
    /// <returns>是否转换成功</returns>
    private async Task<bool> ConvertImageToIconAsync(string origin, string destination, int width, int height)
    {
        try
        {
            if (width > 255 || height > 255)
            {
                return false;
            }

            //var fileExt = Path.GetExtension(origin);
            //var fileNewName = $"{DateTime.Now:HHmmssfff}{fileExt}";
            //var fileDirectory = Path.GetDirectoryName(origin);
            //var fileNewUrl = Path.Combine(AppPath, fileNewName);
            //File.Copy(origin, fileNewUrl);
            using var image = await SixLabors.ImageSharp.Image.LoadAsync(origin);

            // 把原图缩放到指定大小
            image.Mutate(x => x.Resize(width, height));

            // 存放缩放后的原图的内存流
            using (var originImageStream = new MemoryStream())
            {
                // 将缩放后的原图以png格式写入到内存流
                await image.SaveAsync(originImageStream, new PngEncoder());

                // Icon的文件字节内容
                var iconBytes = new List<byte>();

                // 先加载Icon文件头
                iconBytes.AddRange(ICON_HEAD_TEMPLATE);

                // 文件头的第7和8位分别是图标的宽高，修改为设定值，不可大于255
                iconBytes[6] = (byte)width;
                iconBytes[7] = (byte)height;

                // 文件头的第15到第18位是原图片内容部分大小
                var size = BitConverter.GetBytes((int)originImageStream.Length);
                iconBytes[14] = size[0];
                iconBytes[15] = size[1];
                iconBytes[16] = size[2];
                iconBytes[17] = size[3];

                // 追加缩放后原图字节内容
                iconBytes.AddRange(originImageStream.ToArray());

                // 利用文件流保存为Icon文件
                await using (Stream iconFileStream = new FileStream(destination, FileMode.Create))
                {
                    await iconFileStream.WriteAsync(iconBytes.ToArray(), 0, iconBytes.Count);
                }
            }

            return File.Exists(destination);
        }
        catch (Exception ex)
        {
            _messageService.SendMessage($"生成失败，原因：{ex.Message}");
            return false;
        }
    }
}